#ifndef GTL_ENGINE_NETWORK_HEADER_GUARD
#define GTL_ENGINE_NETWORK_HEADER_GUARD

#include "gtlCore.h"
#include <eastl/list.h>
#include <eastl/vector.h>

#include <GTL/external_libs/tinynet/tinynet.h>

namespace GTL { namespace Engine {

	struct ClientConnection
	{
		tn_connection* Connection;
		uint32_t ConnectionID;

		ClientConnection() : Connection(0), ConnectionID(_totalID++) {}
		ClientConnection(tn_connection* conn) : Connection(conn), ConnectionID(_totalID++) {}
		void SendData(void* data, uint16_t size);
		void SendString(const char* str);
		void SendStringF(const char* str, ...);
		void Close();
	private:
		static uint32_t _totalID;
	};

	class NetworkService : public Service
	{
	public:
		virtual void Start();
		virtual int GetPriority() const { return Service::PreUpdate-200; }
		virtual const char* GetName() const { return "Network"; }
		virtual int Do(float dt);
		virtual void Shutdown();

		void StartServer(uint16_t port);
		void StartConnectingToServer(const char* address, uint16_t port);

		void Broadcast(void* data, uint16_t len);
		void Broadcast(const char* text);

		void SendToServer(void* data, uint16_t len);
		void SendToServer(const char* text);
		void SendToServer(const eastl::string& text)
		{
			SendToServer(text.c_str());
		}
		void SendToServer(const GTL::Structures::DataNode& node);

		template <typename T>
		void SendToServer(const T& cos)
		{
			SendToServer((void*)&cos, sizeof(T));
		}
		
		ClientConnection& GetClientConnection();
		ClientConnection* GetConnection(uint32_t id);

		void DestroyPacket(tn_packet* packet);
	protected:
    tn_listener* mServerListener;
    eastl::list<ClientConnection> mConnections;
    ClientConnection mClientConnection;
	};

	namespace Network
	{
		namespace Event
		{
			enum
			{
				NetworkEvent = 'NETE',
				Connected,
				Disconnected,
				CouldNotConnect,
        Connection,
				ClientPacket, /// packet from client
				ServerPacket, /// packet from server
				Disconnection,
			};
		}
	}

	
}}

#endif